package com.conan.dailyflickr.app;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.widget.RemoteViews;


public class BitmapManager_1 {
	private static final String TAG = "DrawableManager";
	private final HashMap<String, Bitmap> bitmapMap;
	private ArrayList<String> mPrepareGetUrl = new ArrayList<String>();
	private ImageDownloadListener mListener;
	private boolean autoUpdate = true;
	private String urlMainID = "";
	
	public BitmapManager_1(ImageDownloadListener listener){
		bitmapMap = new HashMap<String, Bitmap>();
		mListener = listener;
		startThread();
	}
	
	public void clearBitmapItem(String urlString){
		mPrepareGetUrl.remove(urlString);		
		Bitmap bitmap = bitmapMap.remove(urlString);
		if(bitmap != null){
			bitmap.recycle();
			bitmap = null;
		}
	}
	
	public void clearRequestBitmap(){
		mPrepareGetUrl.clear();
	}
	
	public void clearAllBitmap(){
		mPrepareGetUrl.clear();
		Bitmap main = null;
		
		for(String urlString: bitmapMap.keySet()){
			
			Bitmap bitmap = bitmapMap.get(urlString);
			if(bitmap != null){
				if(urlString.compareToIgnoreCase(urlMainID) != 0) {
					bitmap.recycle();
					bitmap = null;
				}else{
					main = bitmap;
				}
			}
		}
		
		bitmapMap.clear();
		// restore main image view
		Log.e(PhotoDailyInfo.TAG, "[restore] +++ " + urlMainID);
		Log.e(PhotoDailyInfo.TAG, "[restore] +++ " + main);
		if(main != null){
			bitmapMap.put(urlMainID, main);
		}
	}
	
	private Bitmap fetchBitmap(String urlString){	
		Log.d(TAG, " image url: " + urlString);
		try{
			InputStream is = fetch(urlString);
			// TODO: save to sdcard later
			//saveToSdcard();
		
			Bitmap bitmap = BitmapFactory.decodeStream(is);
			// bitmapRef = new Bitmap(bitmap);
			bitmapMap.put(urlString, bitmap);
	        Log.d(TAG, "got a thumbnail drawable: " );
	        return bitmap;
	    } catch (MalformedURLException e) {
	        Log.e(TAG, "fetchBtimap failed", e);
	        return null;
	    } catch (IOException e) {
	        Log.e(TAG, "fetchBitmap failed", e);
	        return null;
	    }
	}
	
	
	public int getSize(){
		return bitmapMap.keySet().size();
	}
	
	public boolean fetchAvaiableBitmap(String urlString,  final RemoteViews views, final int viewId){
		// Bitmap bitmapRef = bitmapMap.get(urlString);
		// if (bitmapRef != null) {
			Bitmap bitmap =bitmapMap.get(urlString);
			if (bitmap != null) {
				views.setImageViewBitmap(viewId, bitmap);
				return true;
			}
			//Log.i(PhotoDailyInfo.TAG, "[fetchAvaiableBitmap] ===== " );
			// Reference has expired so remove the key from drawableMap			 
			// bitmapMap.remove(urlString);
			//if(getSize() < 16){
			// addUrlDownload(urlString);		
			// }
			
		//}
		return false;
	}
	
	public boolean checkAvaiableBitmap(String urlString){
		return bitmapMap.containsKey(urlString);
	}
	
	public boolean checkAvaiableRequestBitmap(String urlString){
		return mPrepareGetUrl.contains(urlString);
	}

	
	private void saveToSdcard(){
		Thread thread = new Thread() {
	        @Override
	        public void run() {
	            
	        }
	    };
	    thread.start();	
	}
	
	
	private InputStream fetch(String urlString) throws MalformedURLException, IOException{
		DefaultHttpClient httpClient = new DefaultHttpClient();
		HttpGet request = new HttpGet(urlString);
		HttpResponse response = httpClient.execute(request);
		return response.getEntity().getContent();
	}
	

	
	
	public void fetchBitmapOnThread(final String urlString, int position) {		
		Bitmap bitmap = bitmapMap.get(urlString);
		if (bitmap != null) {
			mListener.completed(false);
			return;
		}

		bitmapMap.remove(urlString);
		if(position < 0){
			urlMainID = urlString;
			addFirstUrlDownload(urlString);
		}else{
			addUrlDownload(urlString);
		}

	}
    
	private void addUrlDownload(String urlString){
		if(mPrepareGetUrl.contains(urlString)) return;
    	synchronized (mPrepareGetUrl) {
			mPrepareGetUrl.add(urlString);
			
			mPrepareGetUrl.notifyAll();
		}
	}
    
	private void addFirstUrlDownload(String urlString){
		if(mPrepareGetUrl.contains(urlString)) return;
    	synchronized (mPrepareGetUrl) {    		
			mPrepareGetUrl.add(0, urlString);
			
			mPrepareGetUrl.notifyAll();
		}
	}
	
    ImageDowloadThread getImageThread; 

	public void startThread(){
		if(getImageThread == null){
			getImageThread = new ImageDowloadThread();
			getImageThread.setName("download_thumb");
			getImageThread.start();
		}
	}

	public void changeConnectionInternet(boolean connected){
		getImageThread.setInternetConnection(connected);
	}

	public void killThread(){		
		if(getImageThread != null){
			Thread t = getImageThread;
			try {
				t.join();				
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			t = null;
		}
	}
	
	class ImageDowloadThread extends Thread{
		private boolean mFlagDoneThread = true;
		private boolean mConnected = true;
		
		public void setInternetConnection(boolean flag){
			mConnected = flag;
		}
		
        @Override
        public void run() {
        	while(mFlagDoneThread){        			
    			while(!mPrepareGetUrl.isEmpty() && mConnected){
    				Log.i(PhotoDailyInfo.TAG, "[download thread] " + mPrepareGetUrl.get(0));
    				//TODO : set imageView to a "pending" image
    				
    				String url = mPrepareGetUrl.remove(0);
    				Bitmap bitmap = fetchBitmap(url);
    				if( bitmap!= null ){
    					// Message message = handler.obtainMessage(1, bitmap);
    					// handler.sendMessage(message);
    					mListener.completed(false);
    					Log.d(PhotoDailyInfo.TAG, "[download thread] done = " + mPrepareGetUrl.size());
    					//autoUpdate = false;
    					// Runtime.getRuntime().freeMemory(); 
    				}else{
    					mPrepareGetUrl.add(url);
    					Log.d(PhotoDailyInfo.TAG, "[download thread] fail" );
    				}
    				
    			}
    			synchronized (mPrepareGetUrl) {		
        			try {
        				mPrepareGetUrl.wait();
        			} catch (InterruptedException e) {
        				// TODO Auto-generated catch block
        				e.printStackTrace();
        			}
        		}
        	}

        }
	};
	
	
	public interface ImageDownloadListener{
		public void completed(boolean largesize); 
	}
	
}
